#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "list.h"

int main(void)
{
    // 创建双向链表对象, 链表本身不限制数据类型，以void*存储，但是建议一个链表只存储一种类型数据，避免读取时类型错误
    DoublyLinkedListObjct listobj_int; // int 类型
    createDoublyLinkedListObjct(&listobj_int);

    // 添加int类型数据
    for (int i = 0; i < 10; i++)
    {
        // 调用lmalloc接口将自动创建数据内存并返回指针，无需手动创建。
        void *_data = listobj_int.lmalloc((void *)&i, sizeof(int));
        // 尾部插入
        listobj_int.push_back(&listobj_int, _data);
    }

    printf("\nlength = %d\n",listobj_int.length(&listobj_int));

    printf("get:\n");
    // 遍历
    for (int i = 0; i < listobj_int.length(&listobj_int); i++)
    {
        int *data = (int *)listobj_int.get(&listobj_int, i);
        printf("%d ", *data);
    }

    printf("\n");
    printf("pop_front:\n");

    // 清空
    //listobj_int.clear(&listobj_int);

    // 从头部依次取出节点
    while(listobj_int.length(&listobj_int) > 0)
    {
        // 从头部取下节点并返回数据指针
        int *data = (int *)listobj_int.pop_front(&listobj_int);
        printf("%d ", *data);
        // 用完记得清除数据内存
        free(data);
    }

    printf("\nlength = %d\n",listobj_int.length(&listobj_int));

    // 字符串类型
    DoublyLinkedListObjct listobj_str; // 字符串类型
    createDoublyLinkedListObjct(&listobj_str);

    // 示例数据
    char *str[] = {"hello", "world", "123", "abc", "def", "ghi", "jkl", "mno", "pqr", "stu"};

    // 添加字符串类型数据
    for (int i = 0; i < 10; i++)
    {
        // 调用lmalloc接口将自动创建数据内存并返回指针，无需手动创建。
        void *_data = listobj_str.lmalloc((void *)str[i], sizeof(char) * (strlen(str[i]) + 1));
        // 头部插入
        listobj_str.push_front(&listobj_str, _data);
    }

    printf("get:\n");
    // 遍历
    for (int i = 0; i < listobj_str.length(&listobj_str); i++)
    {
        char *data = (char *)listobj_str.get(&listobj_str, i);
        printf("%s ", data);
    }

    // 清空
    // listobj_str.clear(&listobj_str);

    printf("\npop_back:\n");
    // 从尾部依次取出节点
    while(listobj_str.length(&listobj_str) > 0)
    {
        // 从尾部取下节点并返回数据指针
        char *data = (char *)listobj_str.pop_back(&listobj_str);
        printf("%s ", data);
        // 用完记得清除数据内存
        free(data);
    }


    // 指针形式创建双向链表对象, 链表本身不限制数据类型，以void*存储，但是建议一个链表只存储一种类型数据，避免读取时类型错误
    DoublyLinkedListObjct *plist_obj_float; // float 类型
    plist_obj_float = (DoublyLinkedListObjct *)malloc(sizeof(DoublyLinkedListObjct));
    createDoublyLinkedListObjct(plist_obj_float);

    // 添加float类型数据
    float fdata = 1.2;
    for (int i = 0; i < 10; i++)
    {
        // 调用lmalloc接口将自动创建数据内存并返回指针，无需手动创建。
        void *_data = plist_obj_float->lmalloc((void *)&fdata, sizeof(float));
        // 尾部插入
        plist_obj_float->push_back(plist_obj_float, _data);
        fdata += 0.2;
    }

    printf("\nlength = %d\n",plist_obj_float->length(plist_obj_float));

    printf("get:\n");
    // 遍历
    for (int i = 0; i < plist_obj_float->length(plist_obj_float); i++)
    {
        float *data = (float *)plist_obj_float->get(plist_obj_float, i);
        printf("%03f ", *data);
    }

    printf("\n");
    printf("pop_front:\n");

    // 清空
    //plist_obj_float->clear(plist_obj_float);

    // 从头部依次取出节点
    while(plist_obj_float->length(plist_obj_float) > 0)
    {
        // 从头部取下节点并返回数据指针
        float *data = (float *)plist_obj_float->pop_front(plist_obj_float);
        printf("%03f ", *data);
        // 用完记得清除数据内存
        free(data);
    }

    printf("\nlength = %d\n",plist_obj_float->length(plist_obj_float));

    free(plist_obj_float);

    return 0;
}